package cn.tedu.oa.common.aspect;
import java.lang.reflect.Method;
import java.util.Date;

import cn.tedu.oa.common.annotation.LogAnnotation;
import cn.tedu.oa.common.exception.ServiceException;
import cn.tedu.oa.common.util.IPUtils;
import cn.tedu.oa.common.util.ShiroUtils;
import cn.tedu.oa.sys.dao.LogDao;
import cn.tedu.oa.sys.entity.Log;
import cn.tedu.oa.sys.entity.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {
    @Autowired
	private LogDao logDao;
	@Pointcut("@annotation(cn.tedu.oa.common.annotation.LogAnnotation)")
	public void logPointCut(){}
	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		//执行方法
		Object result = point.proceed();
		//执行时长(毫秒)
		long time = System.currentTimeMillis() - beginTime;
		//保存日志
		saveSysLog(point, time);
		return result;
	}
	private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
		//签名
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		//方法签名
		Method method = signature.getMethod();
		Class<?> classTarget=joinPoint.getTarget().getClass();
		Class<?>[] par=((MethodSignature) joinPoint.getSignature()).getParameterTypes();
		Method targetMethod=null;
		try {
			targetMethod=classTarget.getMethod(method.getName(), par);
		} catch (Exception e1) {
			e1.printStackTrace();
			throw new ServiceException(e1.getMessage());
		}
		Log log = new Log();
		LogAnnotation requestLog = targetMethod.getAnnotation(LogAnnotation.class);
		if(requestLog != null){
			//注解上的描述
			log.setOperation(requestLog.value());
		}
		//请求的方法名
		String className = joinPoint.getTarget().getClass().getName();
		String methodName = signature.getName();
		log.setMethod(className + "." + methodName + "()");
		//请求的参数
		Object[] args = joinPoint.getArgs();
		if(args!=null&&args.length!=0){
			try{
				//String params = new Gson().toJson(args[0]);//Gson
				String params=new ObjectMapper().writeValueAsString(args[0]);//Jackson
				log.setParams(params);
			}catch (Exception e){
				e.printStackTrace();
			}
		}
		//设置IP地址
		log.setIp(IPUtils.getIpAddr());
		//用户名
		User user=ShiroUtils.getPrincipal();
		String username = null;
		if(user!=null){
			username = ShiroUtils.getPrincipal().getUsername();
		}
		log.setUsername(username);
		//时长
		log.setTime(time);
		log.setIsdel(0);
		//添加时间
		log.setCreatedTime(new Date());
		log.setAddTime(new Date());
		//保存系统日志
		logDao.add(log);
	}
}
